/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package UTIL;

import java.io.UnsupportedEncodingException;

/**
 *http://www.echip.com.vn/echiproot/weblh/suutam/2002/htuni/index.htm
 * @author NxSiHMr0D
 */
public class ConvertString {

    /**
     * enum constants which is used
     */
    enum Contants {

        SURROGATE_LEAD_FIRST(0xD800),
        SURROGATE_TRAIL_FIRST(0xDC00),
        SURROGATE_TRAIL_LAST(0xDFFF);

        Contants(int value) {
            _value = value;
        }
        private int _value;

        /**
         * @return the _value
         */
        public int getValue() {
            return _value;
        }
    }
    /**
     * convert a string to type UTF8
     * @param srcString
     * @return
     * @throws java.io.UnsupportedEncodingException
     */
    public static String ConvertString2UTF8(
            String srcString) throws UnsupportedEncodingException {

//        byte[] UTF8 = srcString.getBytes("UTF8");
//        String result = new String(UTF8, "CP1252");
        /* Cach 2 dang Test*/
        String result = "";
        char[] arraySrc = srcString.toCharArray();
        int lengSrc = arraySrc.length;

        int lengUTF8 = UTF8Length(arraySrc, lengSrc);
        char[] res = UTF8FromUTF16(arraySrc, lengSrc, lengUTF8);
        result = new String(res);
       

        return result;
    }
    /**
     * convert a UTF8 string to String normal
     * @param strUTF8
     * @return
     * @throws java.io.UnsupportedEncodingException
     */
    public static String ConvertUTF82String(
            String strUTF8) throws UnsupportedEncodingException {
//        byte[] UTF8 = strUTF8.getBytes("CP1252");
//
//        String result = new String(UTF8,"UTF8");
         /** Cach 2 dang Test  * */
        int lengUTF8 = strUTF8.length();
        int lengUTF16 = UTF16Length(strUTF8, lengUTF8);
        char[] unicode = UTF16FromUTF8(strUTF8, lengUTF8, lengUTF16);
        String result = new String(unicode);
        
        return result;
    }

//    @SuppressWarnings("empty-statement")
    /**
     * get string UTF8 lenght
     * @param uptr
     * @param tlen
     * @return
     */
    public static int UTF8Length(char[] uptr, int tlen) {
        int len = 0;
        for (int i = 0; i < tlen;) {
            int uch = uptr[i];
            if (uch < 0x80) {
                len++;
            } else if (uch < 0x800) {
                len += 2;
            } else if ((uch >= Contants.SURROGATE_LEAD_FIRST.getValue()) && (uch <= Contants.SURROGATE_TRAIL_LAST.getValue())) {
                len += 4;
                i++;
            } else {
                len += 3;
            }
            i++;
        }
        return len;
    }
    /**
     * convert UTF 8 to UTF 16
     * @param uptr
     * @param tlen
     * @param len
     * @return
     */
    public static char[] UTF8FromUTF16(char[] uptr, int tlen, int len) {
        int k = 0;
        char[] putf = new char[len];
        for (int i = 0; i < tlen;) {
            int uch = uptr[i];
            if (uch < 0x80) {
                putf[k++] = (char) (uch);
            } else if (uch < 0x800) {
                putf[k++] = (char) (0xC0 | (uch >> 6));
                putf[k++] = (char) (0x80 | (uch & 0x3f));
            } else if ((uch >= Contants.SURROGATE_LEAD_FIRST.getValue()) && (uch <= Contants.SURROGATE_TRAIL_LAST.getValue())) {
                // Half a surrogate pair
                i++;
                int xch = 0x10000 + ((uch & 0x3ff) << 10) + (uptr[i] & 0x3ff);
                putf[k++] = (char) (0xF0 | (xch >> 18));
                putf[k++] = (char) (0x80 | (xch >> 12) & 0x3f);
                putf[k++] = (char) (0x80 | ((xch >> 6) & 0x3f));
                putf[k++] = (char) (0x80 | (xch & 0x3f));
            } else {
                putf[k++] = (char) (0xE0 | (uch >> 12));
                putf[k++] = (char) (0x80 | ((uch >> 6) & 0x3f));
                putf[k++] = (char) (0x80 | (uch & 0x3f));
            }
            i++;
        }
        // putf[len] ='\0';
        return putf;
    }
    /**
     * get length of UTF16
     * @param s
     * @param len
     * @return
     */
    public static int UTF16Length(String s, int len) {
        int ulen = 0;
        int charLen;
        for (int i = 0; i < len;) {
            char ch = (char) (s.charAt(i));
            if (ch < 0x80) {
                charLen = 1;
            } else if (ch < 0x80 + 0x40 + 0x20) {
                charLen = 2;
            } else if (ch < 0x80 + 0x40 + 0x20 + 0x10) {
                charLen = 3;
            } else {
                charLen = 4;
                ulen++;
            }
            i += charLen;
            ulen++;
        }
        return ulen;
    }
    /**
     * convert string form UTF16 to UTF8
     * @param s
     * @param len
     * @param tlen
     * @return
     */
    public static char[] UTF16FromUTF8(String s, int len, int tlen) {
        int ui = 0;
        String us = (String) s;
        int i = 0;
        char[] tbuf = new char[tlen];
        while ((i < len) && (ui < tlen)) {
            char ch = (char) us.charAt(i++);
            int d = (int)ch;
            if (ch < 0x80) {
                tbuf[ui] = (char) ch;
            } else if (ch < 0x80 + 0x40 + 0x20) {
                tbuf[ui] = (char) ((ch & 0x1F) << 6);
                ch = (char) us.charAt(i++);
                tbuf[ui] = (char) (tbuf[ui] + (ch & 0x7F));
            } else if (ch < 0x80 + 0x40 + 0x20 + 0x10) {
                tbuf[ui] = (char) ((ch & 0xF) << 12);
                ch = (char) us.charAt(i++);
                tbuf[ui] = (char) (tbuf[ui] + ((ch & 0x7F) << 6));
                ch = (char) us.charAt(i++);
                tbuf[ui] = (char) (tbuf[ui] + (ch & 0x7F));
            } else {
                // Outside the BMP so need two surrogates
                int val = (ch & 0x7) << 18;
                ch = (char) us.charAt(i++);
                val += (ch & 0x3F) << 12;
                ch = (char) us.charAt(i++);
                val += (ch & 0x3F) << 6;
                ch = (char) us.charAt(i++);
                val += (ch & 0x3F);
                tbuf[ui] = (char) (((val - 0x10000) >> 10) + Contants.SURROGATE_LEAD_FIRST.getValue());
                ui++;
                tbuf[ui] = (char) ((val & 0x3ff) + Contants.SURROGATE_TRAIL_FIRST.getValue());
            }
            ui++;
        }
        return tbuf;
    }
}
